<?php

/**
 * 装饰器模式:基于继承实现.
 * 装饰器模式 主要解决继承关系过于复杂的问题，通过组合来替代继承。它主要的作用是给原始类添加增强功能。
 */

/**
 * 文章类
 */
class Article {
    protected $content; //文章内容
    protected $article = null; //文章对象

    public function __construct($content) {
        $this->content = $content;
    }

    public function decorator() {
        return $this->content;
    }

}


/**
 * 编辑人员添加摘要，继承原始的文章类
 */
class Editor extends Article {
    public function __construct(Article $article) {
        $this->article = $article;
    }

    public function decorator() {
        //调用父类的decorator方法，获取父类的content,然后再添加自己的装饰内容,下同
        $this->content = $this->article->decorator() . '【新增摘要from Editor】';
        return $this->content;
    }
}


/**
 * SEO人员添加推广信息
 */
class SEOer extends Article {
    public function __construct(Article $article) {
        $this->article = $article;
    }

    public function decorator() {
        $res = $this->content = $this->article->decorator() . '【新增推广信息from SEOer】';
        return $res;
    }
}


/**
 * 广告人员添加广告信息
 */
class ADer extends Article {
    public function __construct(Article $article) {
        $this->article = $article;
    }

    public function decorator() {
        $res = $this->content = $this->article->decorator() . '【新增广告信息from ADer】';
        return $res;
    }
}

/**
 * todo 根据需要,可以继续装饰其它内容...
 */


//客户端调用
$content = "这是一篇文章";
$article = new Article($content);
//直接发表文章,不装饰任何内容
echo $article->decorator() . PHP_EOL; //这是一篇文章

//Editor先装饰,SEOer再修饰
$client = new SEOer(new Editor($article));
echo $client->decorator() . PHP_EOL; //这是一篇文章【新增摘要from Editor】【新增推广信息from SEOer】

//SEOer先装饰,Editor再修饰,ADer最后装饰
$client = new ADer(new Editor(new SEOer($article)));
echo $client->decorator() . PHP_EOL; //这是一篇文章【新增推广信息from SEOer】【新增摘要from Editor】【新增广告信息from ADer】

//Editor修饰两遍
$client = new Editor(new Editor($article));
echo $client->decorator() . PHP_EOL; //这是一篇文章【新增摘要from Editor】【新增摘要from Editor】
